using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using System.Web;
using System.Web.Mail;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace Halide
{
	/// <summary>
	/// The Compressor class contains methods and properties for compressing and decompressing data.
	/// </summary>
	sealed public class Compressor
	{
		private static string _version = "2008.02.08A";

		/// <summary>
		/// Return the version number of the class; read-only.
		/// </summary>
		/// <value>
		/// A string with the version number of the class.
		/// </value>
		public static string Version
		{
			get
			{
				return _version;
			}
		}

		private Compressor()
	    {
	    }

	    /// <summary>
	    /// GZip compress a string. Only useful for strings over 300 characters in length.
	    /// </summary>
		/// <example>
		/// <code>
		/// string compressedVar = Halide.Compressor.CompressString(stringVar);
		/// </code>
		/// </example>
		/// <param name="text">String to compress.</param>
	    /// <returns>A compressed string.</returns>
	    public static string CompressString(string text)
	    {
	        byte[] buffer = Encoding.UTF8.GetBytes(text);
	        MemoryStream ms = new MemoryStream();
	        using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
	        {
	            zip.Write(buffer, 0, buffer.Length);
	        }

	        ms.Position = 0;

	        byte[] compressed = new byte[ms.Length];
	        ms.Read(compressed, 0, compressed.Length);

	        byte[] gzipBuffer = new byte[compressed.Length + 4];
	        System.Buffer.BlockCopy(compressed, 0, gzipBuffer, 4, compressed.Length);
	        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzipBuffer, 0, 4);
	        return Convert.ToBase64String(gzipBuffer);
	    }

	    /// <summary>
	    /// GZip decompress a string compressed with CompressString().
	    /// </summary>
		/// <example>
		/// <code>
		/// string decompressedVar = Halide.Compressor.DecompressString(compressedVar);
		/// </code>
		/// </example>
		/// <param name="compressedText">String to decompress.</param>
	    /// <returns>A decompressed string.</returns>
	    public static string DecompressString(string compressedText)
	    {
	        byte[] gzipBuffer = Convert.FromBase64String(compressedText);
	        using (MemoryStream ms = new MemoryStream())
	        {
	            int msgLength = BitConverter.ToInt32(gzipBuffer, 0);
	            ms.Write(gzipBuffer, 4, gzipBuffer.Length - 4);

	            byte[] buffer = new byte[msgLength];

	            ms.Position = 0;
	            using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
	            {
	                zip.Read(buffer, 0, buffer.Length);
	            }

	            return Encoding.UTF8.GetString(buffer);
	        }
	    }

	    /// <summary>
	    /// GZip compress a byte array.
	    /// </summary>
		/// <example>
		/// <code>
		/// byte[] compressedVar = Halide.Compressor.Compress(byteBuff);
		/// </code>
		/// </example>
		/// <param name="buffer">Byte array to compress.</param>
	    /// <returns>A compressed byte array.</returns>
	    public static byte[] Compress(byte[] buffer)
	    {
	        MemoryStream ms = new MemoryStream();
	        GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
	        zip.Write(buffer, 0, buffer.Length);
	        zip.Close();
	        ms.Position = 0;

	        byte[] compressed = new byte[ms.Length];
	        ms.Read(compressed, 0, compressed.Length);

	        byte[] gzipBuffer = new byte[compressed.Length + 4];
	        Buffer.BlockCopy(compressed, 0, gzipBuffer, 4, compressed.Length);
	        Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzipBuffer, 0, 4);
	        return gzipBuffer;
	    }

	    /// <summary>
	    /// GZip decompress a byte array.
	    /// </summary>
		/// <example>
		/// <code>
		/// byte[] decompressedVar = Halide.Compressor.Decompress(byteBuff);
		/// </code>
		/// </example>
		/// <param name="gzipBuffer">Byte array to decompress.</param>
	    /// <returns>A decompressed byte array.</returns>
	    public static byte[] Decompress(byte[] gzipBuffer)
	    {
	        MemoryStream ms = new MemoryStream();
	        int msgLength = BitConverter.ToInt32(gzipBuffer, 0);
	        ms.Write(gzipBuffer, 4, gzipBuffer.Length - 4);

	        byte[] buffer = new byte[msgLength];

	        ms.Position = 0;
	        GZipStream zip = new GZipStream(ms, CompressionMode.Decompress);
	        zip.Read(buffer, 0, buffer.Length);

	        return buffer;
	    }

        // Outer Identify class
    }

    // Outer namespace
}